"""
数据库初始化和管理模块
使用Tortoise-ORM实现数据库操作
"""

import time
import asyncio
from typing import Optional, Dict, Any
from tortoise import Tortoise, connections
from tortoise.exceptions import DBConnectionError, OperationalError
from datetime import datetime

from app.core.config import settings
from app.utils.app_log import logger
from app.models import TORTOISE_ORM_MODELS


class DatabaseManager:
    """数据库管理器"""
    
    def __init__(self):
        self.is_initialized = False
        
    def get_database_config(self) -> Dict[str, Any]:
        """获取数据库配置"""
        return {
            "connections": {
                "default": {
                    "engine": "tortoise.backends.mysql",
                    "credentials": {
                        "host": settings.database_host,
                        "port": settings.database_port,
                        "user": settings.database_user,
                        "password": settings.database_password,
                        "database": settings.database_name,
                        "minsize": 1,
                        "maxsize": settings.database_pool_size,
                        "charset": "utf8mb4",
                        "echo": settings.database_echo
                    }
                }
            },
            "apps": {
                "models": {
                    "models": TORTOISE_ORM_MODELS + ["aerich.models"],
                    "default_connection": "default",
                }
            },
            "timezone": "Asia/Shanghai"
        }
    
    async def check_database_connection(self) -> bool:
        """检查数据库连接"""
        try:
            config = self.get_database_config()
            await Tortoise.init(config=config)
            
            # 测试连接
            connection = connections.get("default")
            await connection.execute_query("SELECT 1")
            
            await Tortoise.close_connections()
            logger.info("数据库连接测试成功")
            return True
            
        except Exception as e:
            logger.error(f"数据库连接测试失败: {str(e)}")
            return False
    
    async def create_database_if_not_exists(self) -> bool:
        """创建数据库（如果不存在）"""
        try:
            # 先连接到mysql系统数据库
            database_name = settings.database_name
            system_config = self.get_database_config()
            system_config["connections"]["default"]["credentials"]["database"] = "mysql"
            
            await Tortoise.init(config=system_config)
            connection = connections.get("default")
            
            # 检查数据库是否存在
            result = await connection.execute_query(
                f"SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = '{database_name}'"
            )
            
            if not result[1]:  # 数据库不存在
                # 创建数据库
                await connection.execute_query(
                    f"CREATE DATABASE IF NOT EXISTS `{database_name}` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci"
                )
                logger.info(f"数据库 {database_name} 创建成功")
            else:
                logger.info(f"数据库 {database_name} 已存在")
            
            await Tortoise.close_connections()
            return True
            
        except Exception as e:
            logger.error(f"创建数据库失败: {str(e)}")
            return False
    
    async def initialize_database(self, create_tables: bool = True) -> bool:
        """初始化数据库"""
        # 检查是否启用数据库功能
        if not settings.enable_database:
            logger.info("数据库功能已禁用，跳过初始化")
            return True
            
        start_time = time.time()
        
        try:
            logger.info("开始初始化数据库...")
            
            # 1. 检查数据库连接
            if not await self.check_database_connection():
                # 尝试创建数据库
                if not await self.create_database_if_not_exists():
                    raise Exception("无法创建数据库")
            
            # 2. 初始化Tortoise-ORM
            config = self.get_database_config()
            await Tortoise.init(config=config)
            
            # 3. 创建数据表
            if create_tables and settings.database_auto_create:
                await Tortoise.generate_schemas()
                logger.info("数据表创建/更新完成")
            
            # 4. 记录初始化日志（只在启用数据库时）
            if settings.enable_database:
                await self._log_database_init("success", time.time() - start_time)
            
            self.is_initialized = True
            logger.info(f"数据库初始化完成，耗时: {time.time() - start_time:.2f}秒")
            return True
            
        except Exception as e:
            error_msg = f"数据库初始化失败: {str(e)}"
            logger.error(error_msg)
            
            # 记录失败日志
            if settings.enable_database:
                try:
                    await self._log_database_init("failed", time.time() - start_time, error_msg)
                except:
                    pass
                
            return False
    
    async def _log_database_init(self, status: str, execution_time: float, message: str = None):
        """记录数据库初始化日志"""
        try:
            from app.models.base.system import DatabaseInitLog
            
            await DatabaseInitLog.create(
                version="1.0.0",
                init_type="auto",
                status=status,
                message=message or f"数据库初始化{status}",
                execution_time=execution_time
            )
        except Exception as e:
            logger.warning(f"记录初始化日志失败: {str(e)}")
    
    async def close_database(self):
        """关闭数据库连接"""
        try:
            await Tortoise.close_connections()
            self.is_initialized = False
            logger.info("数据库连接已关闭")
        except Exception as e:
            logger.error(f"关闭数据库连接失败: {str(e)}")
    
    async def init_default_data(self):
        """初始化默认数据"""
        # 检查是否启用自动初始化数据
        if not settings.enable_auto_init_data:
            logger.info("自动初始化数据功能已禁用，跳过初始化")
            return
            
        # 检查是否启用数据库
        if not settings.enable_database:
            logger.info("数据库功能已禁用，跳过默认数据初始化")
            return
            
        try:
            logger.info("开始初始化默认数据...")
            
            # 创建默认管理员用户（只在启用用户系统时）
            if settings.enable_user_system:
                await self._create_default_admin()
            
            # 创建默认系统配置
            await self._create_default_configs()
            
            logger.info("默认数据初始化完成")
            
        except Exception as e:
            logger.error(f"初始化默认数据失败: {str(e)}")
    
    async def _create_default_admin(self):
        """创建默认管理员用户"""
        # 检查是否启用用户系统
        if not settings.enable_user_system:
            logger.info("用户系统已禁用，跳过默认管理员创建")
            return
            
        try:
            from app.models import User
            from app.utils.user import get_password_hash
            
            # 检查是否已存在管理员
            admin_exists = await User.filter(username="admin", is_deleted=False).exists()
            
            if not admin_exists:
                admin_user = await User.create(
                    username="admin",
                    email="admin@example.com",
                    hashed_password=get_password_hash("123456"),
                    full_name="系统管理员",
                    is_active=True,
                    is_superuser=True
                )
                logger.info(f"默认管理员用户创建成功: {admin_user.username}")
            else:
                logger.info("默认管理员用户已存在")
                
        except Exception as e:
            logger.error(f"创建默认管理员失败: {str(e)}")
    
    async def _create_default_configs(self):
        """创建默认系统配置"""
        try:
            from app.models import SystemConfig
            
            default_configs = [
                {
                    "key": "system_name", 
                    "value": "FastAPI通用基础项目", 
                    "description": "系统名称",
                    "config_type": "string",
                    "is_public": True
                },
                {
                    "key": "system_version", 
                    "value": "1.0.0", 
                    "description": "系统版本",
                    "config_type": "string",
                    "is_public": True
                },
                {
                    "key": "enable_user_registration", 
                    "value": str(settings.enable_user_registration), 
                    "description": "是否启用用户注册",
                    "config_type": "boolean",
                    "is_public": True
                },
                {
                    "key": "max_login_attempts", 
                    "value": "5", 
                    "description": "最大登录尝试次数",
                    "config_type": "integer",
                    "is_public": False
                },
                {
                    "key": "session_timeout", 
                    "value": "3600", 
                    "description": "会话超时时间(秒)",
                    "config_type": "integer",
                    "is_public": False
                }
            ]
            
            for config_data in default_configs:
                await SystemConfig.set_config(**config_data)
            
            logger.info("默认系统配置创建完成")
            
        except Exception as e:
            logger.error(f"创建默认系统配置失败: {str(e)}")
    
    async def get_database_status(self) -> Dict[str, Any]:
        """获取数据库状态信息"""
        try:
            if not self.is_initialized:
                return {
                    "status": "disconnected",
                    "message": "数据库未初始化"
                }
            
            # 检查连接状态
            connection = connections.get("default")
            await connection.execute_query("SELECT 1")
            
            # 获取数据库信息
            tables_result = await connection.execute_query(
                "SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = DATABASE()"
            )
            
            return {
                "status": "connected",
                "database_name": settings.database_name,
                "host": settings.database_host,
                "port": settings.database_port,
                "tables_count": len(tables_result[1]) if tables_result[1] else 0,
                "tables": [row[0] for row in tables_result[1]] if tables_result[1] else [],
                "connection_pool_size": settings.database_pool_size
            }
            
        except Exception as e:
            return {
                "status": "error",
                "message": str(e)
            }


# 全局数据库管理器实例
db_manager = DatabaseManager()


# 便捷函数
async def init_database() -> bool:
    """初始化数据库的便捷函数"""
    return await db_manager.initialize_database()


async def close_database():
    """关闭数据库连接的便捷函数"""
    await db_manager.close_database()


async def get_database_status() -> Dict[str, Any]:
    """获取数据库状态的便捷函数"""
    return await db_manager.get_database_status()